<template>
  <template v-if="!(!state.visible && !state.keepAlive)">
    <view v-if="layoutPos.layout === 'FLEX'" :class="colClass" :style="flexStyle">
      <slot></slot>
    </view>
    <uni-col v-else :class="colClass" :style="cssVars" v-bind="gridAttrs">
      <slot></slot>
    </uni-col>
  </template>
</template>
<script lang="ts">
export default {
  options: {
    addGlobalClass: true,
    virtualHost: true,
    styleIsolation: "shared"
  },
}
</script>
<script setup lang="ts">
import { useNamespace } from "@/use";
import { computed } from "vue";
import { calcGridLayoutPos } from "@ibiz-template/runtime";
import type { IGridLayoutPos, IFlexLayoutPos } from "@ibiz/model-core";
import { colProps } from './i-biz-col'

const ns = useNamespace("col");

const props = defineProps(colProps);

/**
 * 计算间距类名
 */
const spacingClass = computed(() => {
  const ns2 = useNamespace("spacing");
  const classArr: string[] = [];
  const spacings: IData = {
    top: props.layoutPos!.spacingTop,
    bottom: props.layoutPos!.spacingBottom,
    left: props.layoutPos!.spacingLeft,
    right: props.layoutPos!.spacingRight,
  };
  Object.keys(spacings).forEach((position) => {
    const value = spacings[position] as string;
    if (!value) {
      return;
    }
    classArr.push(ns2.bm(position, value.toLowerCase()));
  });
  return classArr;
});

// 计算栅格布局的属性
const gridAttrs = computed(() => {
  const gridLayoutPos = props.layoutPos as IGridLayoutPos;
  // FLEX布局时不计算
  if (gridLayoutPos.layout === "FLEX") {
    return {};
  }

  return calcGridLayoutPos(gridLayoutPos);
});

const cssVars = computed(() => {
  if (props.state) {
    const layout = props.state.layout;
    const styles = {
      width: layout.width,
      height: layout.height,
    };
    Object.assign(styles, layout.extraStyle);
    return styles;
  }
  return {};
});

const colClass = computed(() => {
  const classNames: string[] = [
    ns.b(),
    props.layoutPos?.layout === "FLEX" ? ns.m("flex") : ns.m("grid"),
    ...spacingClass.value,
  ];
  if (props.state) {
    classNames.push(
      ns.is("hidden", !props.state.visible),
      props.state.layout.extraClass as unknown as string
    );
  }
  return classNames;
});

const flexStyle = computed(() => {
  const pos = props.layoutPos as IFlexLayoutPos;
  return {
    flexGrow: pos.grow,
    flexShrink:
    pos.shrink === 1
        ? undefined
        : pos.shrink,
    flexBasis: `${pos.basis}px}`,
    ...cssVars.value,
  };
});
</script>
<style lang="scss">
@include b(col) {
  min-height: 1px;

  @include m(flex) {
    min-width: 0;

    // 修复flex时flex-grow和flex-shrink时高度被内容撑开，没法压缩
    min-height: 0;
  }

  @include when(hidden) {
    display: none;
  }
}

@include b(spacing-top) {
  @include m(outersmall) {
    margin-top: 8px;
  }

  @include m(outermedium) {
    margin-top: 16px;
  }

  @include m(outerlarge) {
    margin-top: 24px;
  }

  @include m(outernone) {
    margin-top: 0px;
  }

  @include m(innersmall) {
    padding-top: 8px;
  }

  @include m(innermedium) {
    padding-top: 16px;
  }

  @include m(innerlarge) {
    padding-top: 24px;
  }

  @include m(innernone) {
    padding-top: 0px;
  }
}

@include b(spacing-bottom) {
  @include m(outersmall) {
    margin-bottom: 8px;
  }

  @include m(outermedium) {
    margin-bottom: 16px;
  }

  @include m(outerlarge) {
    margin-bottom: 24px;
  }

  @include m(outernone) {
    margin-bottom: 0px;
  }

  @include m(innersmall) {
    padding-bottom: 8px;
  }

  @include m(innermedium) {
    padding-bottom: 16px;
  }

  @include m(innerlarge) {
    padding-bottom: 24px;
  }

  @include m(innernone) {
    padding-bottom: 0px;
  }
}

@include b(spacing-left) {
  @include m(outersmall) {
    margin-left: 8px;
  }

  @include m(outermedium) {
    margin-left: 16px;
  }

  @include m(outerlarge) {
    margin-left: 24px;
  }

  @include m(outernone) {
    margin-left: 0px;
  }

  @include m(innersmall) {
    padding-left: 8px;
  }

  @include m(innermedium) {
    padding-left: 16px;
  }

  @include m(innerlarge) {
    padding-left: 24px;
  }

  @include m(innernone) {
    padding-left: 0px;
  }
}

@include b(spacing-right) {
  @include m(outersmall) {
    margin-right: 8px;
  }

  @include m(outermedium) {
    margin-right: 16px;
  }

  @include m(outerlarge) {
    margin-right: 24px;
  }

  @include m(outernone) {
    margin-right: 0px;
  }

  @include m(innersmall) {
    padding-right: 8px;
  }

  @include m(innermedium) {
    padding-right: 16px;
  }

  @include m(innerlarge) {
    padding-right: 24px;
  }

  @include m(innernone) {
    padding-right: 0px;
  }
}
</style>
